/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tesis2.pucp.Maestros.Binpacking;

import com.tesis2.pucp.Envio.DAO.PedidoDAO;
import com.tesis2.pucp.Envio.DAO.VehiculoDAO;
import com.tesis2.pucp.Modelo.TesisPedido;
import com.tesis2.pucp.Modelo.TesisProducto;
import com.tesis2.pucp.Modelo.TesisVehiculo;
import java.util.ArrayList;
import java.util.Date;

/**
 *
 * @author pachon
 */
public class Voraz {
    
    ArrayList<Resultado> listaResultados;
    ArrayList<TesisPedido> listaPedidos;
    ArrayList<TesisProducto> listaProductos;
    ArrayList<TesisVehiculo> listaVehiculos;
    int maxAlto,maxAncho,maxLargo;
    boolean flag = true;
    int valor;
    int matrizCapacidad[][][];
    
    public TesisVehiculo obtenerVehiculo(Date horaInicial, Date horaFinal){
        
        TesisVehiculo vehiculo = new TesisVehiculo();
        int i = 0;
        if(flag){
            for(TesisVehiculo c: listaVehiculos){
            
            if(c.getTesisHorario().getEntrada().after(horaInicial)&&c.getTesisHorario().getSalida().after(horaFinal)){
                vehiculo = c;
                break;
            }
            i++;
            }
            if(i== listaVehiculos.size()){
                flag = false;
                vehiculo = listaVehiculos.get(0);
                listaVehiculos.remove(0);
            }else{
                listaVehiculos.remove(i);
            }
        }else{
            vehiculo = listaVehiculos.get(0);
            listaVehiculos.remove(0);
        }
        
        return vehiculo;
    }
    
    public ArrayList<Resultado> Voraz(ArrayList<TesisPedido> lista, Date horaInicial, Date horaFinal){
        
        VehiculoDAO dao = new VehiculoDAO();
        listaVehiculos = dao.listarVehiculos();
        TesisVehiculo vehiculo = new TesisVehiculo();
        listaResultados = new ArrayList<>();
        
        while(lista.size()>0){
            
            Resultado result = new Resultado();
            ArrayList<TesisPedido> listaPedidos = new ArrayList<>();
            vehiculo = obtenerVehiculo(horaInicial, horaFinal);
            result.vehiculo = vehiculo;
            TesisPedido pedido = lista.get(0);
            lista.remove(0);
            
            maxAlto = vehiculo.getAlto()*100;
            maxAncho = vehiculo.getAncho()*100;
            maxLargo = vehiculo.getLargo()*100;
            matrizCapacidad = new int [maxAlto][maxLargo][maxAncho];
            inicializar(matrizCapacidad);
            
            while(llenarVehiculo(pedido, matrizCapacidad)){
                listaPedidos.add(0,pedido);
                if(lista.size()>0){
                   pedido = lista.get(0);
                   lista.remove(0);
                }else{
                   break;
                }
                
            }
            result.litsaPedidos = listaPedidos;
            listaResultados.add(result);
        }
        
        
        return listaResultados;
    }

    private void inicializar(int[][][] matrizCapacidad) {
        
        for(int i = 0; i<maxAlto;i++){
            for(int j = 0; j<maxLargo;j++){
                for(int k = 0; k<maxAncho;k++){
                    matrizCapacidad[i][j][k]=0;
                }
            }
        }
    }

    private boolean llenarVehiculo(TesisPedido pedido, int[][][] matrizCapacidad) {
        
        PedidoDAO dao = new PedidoDAO();
        listaProductos = dao.listarProductos(pedido);
        
        for(TesisProducto c: listaProductos){
            
            if(!llenarProducto(c)){
                return false;
            }
            
        }
        
        return true;
    }

    private boolean llenarProducto(TesisProducto c) {
        
        for(int i = 0; i<maxAlto;i++){
            for(int j = 0; j<maxLargo;j++){
                for(int k = 0; k<maxAncho;k++){
                    if(matrizCapacidad[i][j][k]!=1){
                        if(i+c.getAlto()<maxAlto){
                            if(j+c.getLargo()<maxLargo){
                                if(k+c.getAncho()<maxAncho){
                                    
                                    if(!SepuedePintar(i,j,k,c)){
                                        pintar(i,j,k,c);
                                        return true;
                                    }
                                    
                                }
                            }
                        }
                    }
                }
            }
        }
        
        return false;
    }

    private boolean SepuedePintar(int i, int j, int k, TesisProducto c) {
        
        for(int x = i; x<i+c.getAlto();x++){
            for(int y = j; y<j+c.getLargo();y++){
                for(int z = k; z<k+c.getAncho();z++){
                    
                    if(matrizCapacidad[x][y][z]==1){
                       return false; 
                    }
                }
            }
        }
        
        return true;
    }

    private void pintar(int i, int j, int k, TesisProducto c) {
        
        for(int x = i; x<i+c.getAlto();x++){
            for(int y = j; y<j+c.getLargo();y++){
                for(int z = k; z<k+c.getAncho();z++){
                    
                    matrizCapacidad[x][y][z]=1;   
                    
                }
            }
        }
        
    }
    
    
    
}
